What Are Generics in C#?

Generics in C# are a feature that allows you to define classes, methods, and data structures with a placeholder for the data type they operate on. This provides a way to write code that can work with any data type while still maintaining type safety. Generics enable developers to create reusable and type-safe code, which can reduce runtime errors and improve performance.

Key Features of Generics

Type Safety: 

Generics enforce type safety by ensuring that the data type used is consistent throughout the code. This means that type-related errors can be caught at compile time, rather than at runtime.

Reusability: 

By using generics, you can create classes and methods that work with any data type. This reduces code duplication because you don't have to create multiple versions of the same code for different data types.

Performance: 

Generics can improve performance because they avoid the need for boxing and unboxing, which are common with non-generic collections and methods.

How Generics Work?

Generics allow you to define a type parameter that can be replaced with any type when the generic is instantiated. Here’s how it works:

Generic Classes: 

A generic class allows you to create a class that can work with any data type. The type parameter is specified in angle brackets <T>.

public class GenericClass<T>
{
    private T data;

    public void SetData(T value)
    {
        data = value;
    }

    public T GetData()
    {
        return data;
    }

}


Usage Example:

GenericClass<int> intInstance = new GenericClass<int>();
intInstance.SetData(5);
int value = intInstance.GetData();

GenericClass<string> stringInstance = new GenericClass<string>();
stringInstance.SetData("Hello");
string text = stringInstance.GetData();


In this example, GenericClass<T> works with both int and string types, demonstrating its flexibility.

Generic Methods: 

Methods that operate on a type parameter, specified when the method is called. This allows the method to be type-safe and flexible.


public void Swap<T>(ref T a, ref T b)
{
    T temp = a;
    a = b;
    b = temp;
}


Usage Example:


int x = 10, y = 20;
Swap<int>(ref x, ref y);

string first = "Hello", second = "World";
Swap<string>(ref first, ref second);


The Swap<T> method can swap values of any data type.

Common Use Cases for Generics:

Generic Collections: 

Classes like List<T>, Dictionary<TKey, TValue>, and Queue<T> in the System.Collections.Generic namespace use generics to allow storing and managing collections of data with type safety.

Generic Interfaces: 

Interfaces that use type parameters to define type-safe operations. For example, IComparable<T> and IEnumerable<T>.

Generic Delegates: 

Delegates like Func<T> and Action<T> are generic, allowing you to define type-safe callbacks and event handlers.

Constraints in Generics: 

You can impose constraints on generic types to restrict the types that can be used with the generic class or method. For example, using the where clause to specify that a type must implement a particular interface or inherit from a specific class.


public class Repository<T> where T : class
{
    // T must be a class type
}

Post a Comment

0 Comments